/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package compilador.analisadorSintatico.operacoes;

import compilador.analisadorLexico.Token;
import compilador.analisadorLexico.TokenClass;
import compilador.analisadorSintatico.Producao;
import compilador.analisadorSintatico.TokenReader;
import compilador.analisadorSintatico.metodos.CHAMADA_METODO;
import compilador.analisadorSintatico.metodos.VARIAVEL;
import compilador.analisadorSintatico.simboloGramatical.NaoTerminal;
import compilador.analisadorSintatico.simboloGramatical.SimboloGramatical;
import compilador.analisadorSintatico.simboloGramatical.Terminal;

/**
 *
 * @author Joaquim Ranyere
 */
public class EXP extends Producao {

    @Override
    public void setSimbolo() {
        this.simbolo = new NaoTerminal(this.getClass().getSimpleName());
    }

    @Override
    public SimboloGramatical derivar() throws Exception {
        TokenReader tokenReader = TokenReader.getInstance();

        Token token = tokenReader.seeCurrent();

        // Trata os !...
        if (token.getTokenClass().equals(TokenClass.OPERADOR) && token.getAtributo().equals("!")) {

            ((NaoTerminal) this.simbolo).add(new Terminal(token));
            token = tokenReader.consome();

            if (tokenReader.seeCurrent().getTokenClass().equals(TokenClass.DELIMITADOR) && tokenReader.seeCurrent().getAtributo().equals("(")) {
                ((NaoTerminal) this.simbolo).add(new EXP().derivar());
            }
            if (tokenReader.seeCurrent().getTokenClass().equals(TokenClass.DELIMITADOR) && tokenReader.seeCurrent().getAtributo().equals(")")) {
                ((NaoTerminal) this.simbolo).add(new Terminal(token));
                token = tokenReader.consome();
            }

            if (tokenReader.seeCurrent().getAtributo().equals("(")) {
                //Pode ser uma chamada de método
                ((NaoTerminal) this.simbolo).add(new CHAMADA_METODO().derivar());
            } else {
                //Pode ser uma variavel         
                ((NaoTerminal) this.simbolo).add(new VARIAVEL().derivar());
            }
        // Trata os demais
        } else {

            ((NaoTerminal) this.simbolo).add(new EXP_REL().derivar());
            // Esta analise condicional � repetida dentro do objeto OP_LOGIC. Otimizarei a gramatica e 
            // este c�digo depois. Not enough time, for now.
            if (isLOGIC(tokenReader.seeCurrent())) {
                ((NaoTerminal) this.simbolo).add(new OP_LOGIC().derivar());

                ((NaoTerminal) this.simbolo).add(new EXP_REL().derivar());
            }
        }


        return ((NaoTerminal) this.simbolo);


    }

    public boolean isLOGIC(Token t) {

        if (t.getTokenClass().equals(TokenClass.OPERADOR) &&
                (t.getAtributo().equals("||") || t.getAtributo().equals("&&"))) {
            return true;
        } else {
            return false;
        }
    }
}
